using System;
using System.Collections.Generic;
using System.Linq;
using Db4objects.Db4o.Linq;
using SharedObjects;
using TheGameLib;

namespace TheGame.Webservices
{
	/// <summary>
	/// This is the usenet simulation
	/// </summary>
	public partial class TheGameService
	{
		public List<UsenetMessage> Usenet_GetThreads(Guid sessionId, ulong systemId, DateTime fromDate, DateTime toDate)
		{
			Agent me;
			AgentSessionObject aso;
			AgentConnection conn;
			if (!ValidateAgentSessionAndConnection(sessionId, systemId, out me, out aso, out conn))
				return null;

			var threads = (from UsenetMessage msg in Db where msg.RootPostId == 0 select msg).ToList();
			return threads;
		}

		public List<UsenetMessage> Usenet_GetThreadMessages(Guid sessionId, ulong systemId, ulong rootMessageId)
		{
			Agent me;
			AgentSessionObject aso;
			AgentConnection conn;
			if (!ValidateAgentSessionAndConnection(sessionId, systemId, out me, out aso, out conn))
				return null;
			var messages = (from UsenetMessage msg in Db where msg.RootPostId == rootMessageId select msg).ToList();
			return messages;
		}

		public bool Usenet_PostMessage(Guid sessionId, ulong systemId, UsenetMessage msg)
		{
			Agent me;
			AgentSessionObject aso;
			AgentConnection conn;
			if (!ValidateAgentSessionAndConnection(sessionId, systemId, out me, out aso, out conn))
				return false;
			
			if (me.UsenetAccount == null || me.UsenetAccount.AccountStatus != UsenetAccountStatus.Active)
			{
				SendServerError(ServerErrorSeverity.Error, "Your usenet account is not allowed to post.");
				return false;
			}
			if(msg.Body == null)
			{
				SendServerError(ServerErrorSeverity.Error, "Body must not be empty.");
				return false;
			}
			if(msg.Body.Length > 1024)
			{
				SendServerError(ServerErrorSeverity.Error, "The maximum message size of 1024 characters is exceeded.");
				return false;
			}
			//do recaptcha check here.

			if (msg.ReplyToPostId != 0)
			{
				UsenetMessage root = (from UsenetMessage m in Db where m.Id == msg.ReplyToPostId select m).FirstOrDefault();
				if (root == null)
				{
					SendServerError(ServerErrorSeverity.Error, "Usenet post contains invalid thread id.");
					return false;
				}
				root.HasFollowUps = true;
				Db.PersistEntity(root);
			}
			EmailAccount posterEmailAccount = (from EmailAccount ea in me.EmailAccounts where ea.Id == me.UsenetAccount.EmailAccountId select ea).FirstOrDefault();
			if(posterEmailAccount == null)
			{
				SendServerError(ServerErrorSeverity.Error, "Your usenet account does not have a valid email account associated.");
				return false;
			}
			ComputerSystem emailServer = (from ComputerSystem cs in Db where cs.Id == posterEmailAccount.SystemId select cs).FirstOrDefault();
			if(emailServer == null)
			{
				SendServerError(ServerErrorSeverity.Error, "The email account associated with your usenet account is corrupt (invalid mail server). Please contact technical support.");
				return false;
			}

			string from = string.Format("{0}@{1}", posterEmailAccount.Name, emailServer.GetHostname());
			UsenetMessage message = new UsenetMessage
			{
				Id = Guid.NewGuid().ToLong(),
				FromAccountId = me.UsenetAccount.Id,
				Subject = msg.Subject,
				Body = msg.Body,
				ReplyToPostId = msg.ReplyToPostId,
				RootPostId = msg.RootPostId,
				TimeStamp = DateTime.Now,
				From = from
			};
			Db.Store(message);
			Db.Commit();
			return true;
		}

		/// <summary>
		/// This one shall be used once recaptchas can be used programmatically via some google API,
		/// and i don't see this coming any time soon.
		/// </summary>
		/// <param name="sessionId"></param>
		/// <param name="systemId"></param>
		/// <returns></returns>
		public byte[] UsenetGetRecaptcha(Guid sessionId, ulong systemId)
		{
			Agent me;
			AgentSessionObject aso;
			AgentConnection conn;
			if (!ValidateAgentSessionAndConnection(sessionId, systemId, out me, out aso, out conn))
				return null;
			return null;
		}
	}
}